package com.chat.admin.utils;

import com.chat.common.entity.FileMap;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

import static com.chat.admin.common.constant.DataConstant.DATE_FORMAT;
import static com.chat.admin.common.constant.DataConstant.YEAR_FORMAT;

@Service
@Slf4j
public class FileUploadUtil {

    // SFTP配置
    @Value("${sftp.host}")
    private String sftpHost;

    @Value("${sftp.port}")
    private Integer sftpPort;

    @Value("${sftp.user}")
    private String sftpUser;

    @Value("${sftp.password}")
    private String sftpPassword;

    public FileMap uploadFile(MultipartFile file, String[] pathSegments) throws IOException {
        log.info("正在上传文件");
        Session session = null;
        Channel channel = null;
        ChannelSftp sftp = null;
        try {
            // 获取当前日期
            Date now = new Date();
            String year = YEAR_FORMAT.format(now);
            String date = DATE_FORMAT.format(now);

            // 创建JSch对象
            JSch jsch = new JSch();
            log.info("sftpUser: " + sftpUser);
            log.info("sftpHost: " + sftpHost);
            log.info("sftpPort: " + sftpPort);
            session = jsch.getSession(sftpUser, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            channel = session.openChannel("sftp");
            channel.connect();

            sftp = (ChannelSftp) channel;

            // 创建目录
            String basePath = "/E-chat/data";
            String[] folders = {year, date};
            folders = Arrays.copyOf(folders, folders.length + pathSegments.length);
            System.arraycopy(pathSegments, 0, folders, folders.length - pathSegments.length, pathSegments.length);
            for (String folder : folders) {
                basePath = basePath + "/" + folder;
                try {
                    sftp.cd(basePath);
                } catch (SftpException e) {
                    sftp.mkdir(basePath);
                    sftp.cd(basePath);
                }
            }

            //TODO:上传文件中文乱码
            // 上传文件
            String originalFilename = file.getOriginalFilename();
            String baseName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileNameId = System.currentTimeMillis() + "" + UUID.randomUUID();
            String fileName = baseName + "_" + fileNameId + extension;
            try (InputStream inputStream = file.getInputStream()) {
                sftp.put(inputStream, basePath + "/" + fileName);
            }

            FileMap fileMap = new FileMap();
            fileMap.setFileId(fileNameId);
            fileMap.setFilePath(basePath + "/" + fileName);
            log.info("上传文件完成");
            return fileMap;
        } catch (Exception e) {
            // 打印完整的异常堆栈信息
            log.error("An error occurred", e);
            throw new IOException("文件上传失败");
        } finally {
            // 关闭连接
            if (sftp != null) {
                sftp.disconnect();
            }
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }

    public Resource getFile(String filePath) throws IOException {
        Session session = null;
        Channel channel = null;
        ChannelSftp sftp = null;
        try {
            // 创建JSch对象
            JSch jsch = new JSch();
            log.info("sftpUser: " + sftpUser);
            log.info("sftpHost: " + sftpHost);
            log.info("sftpPort: " + sftpPort);
            session = jsch.getSession(sftpUser, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            channel = session.openChannel("sftp");
            channel.connect();

            sftp = (ChannelSftp) channel;
            log.info("正在获取文件");
            InputStream inputStream = sftp.get(filePath);
            return new InputStreamResource(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("An error occurred", e);
            log.info("文件获取失败");
            throw new IOException("文件获取失败");
        } finally {
            // 关闭连接
            if (sftp != null) {
                sftp.disconnect();
            }
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }

    public void deleteFile(String filePath) throws IOException {
        Session session = null;
        Channel channel = null;
        ChannelSftp sftp = null;
        try {
            // 创建JSch对象
            JSch jsch = new JSch();
            log.info("sftpUser: " + sftpUser);
            log.info("sftpHost: " + sftpHost);
            log.info("sftpPort: " + sftpPort);
            session = jsch.getSession(sftpUser, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            channel = session.openChannel("sftp");
            channel.connect();

            sftp = (ChannelSftp) channel;
            log.info("正在删除文件");
            // 删除文件
            sftp.rm(filePath);
        } catch (Exception e) {
            // 打印完整的异常堆栈信息
            log.error("An error occurred", e);
            log.info("文件删除失败");
            throw new IOException("删除文件失败");
        } finally {
            // 关闭连接
            if (sftp != null) {
                sftp.disconnect();
            }
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }
}

